﻿using UnityEngine;
using System.Collections;
using System;

namespace GameBasic
{
    [Serializable]
    public class Task<T> : ITask
    {
        // Data
        public TimeCounter timer;
        public int id;
        public T data;
        float progress;

        // Callbacks
        public Action<Task<T>> onStart;
        public Action<Task<T>> onUpdate;
        public Action<Task<T>> onStop;

        public float Progress => progress;

        public TaskStatus Status { get; set; }

        public bool IsRunning => Status == TaskStatus.Running;
        public bool IsComplete => Status == TaskStatus.End;

        public bool Stop
        {
            get => Status == TaskStatus.Stop;
            set => Status = value ? TaskStatus.Stop : Status;
        }

        public bool Kill
        {
            get => Status == TaskStatus.Kill;
            set => Status = value ? TaskStatus.Kill : Status;
        }

        public Task()
        {

        }

        public Task(T data)
        {
            this.data = data;
        }

        public Task(float time)
        {
            SetDuration(time);
        }

        public void SetDuration(float duration)
        {
            timer.enable = true;
            timer.target = duration;
        }

        public void Schedule()
        {
            TaskRunner.AddToDefault(this);
        }

        public void OnStart()
        {
            progress = 0;
            timer.Start();
            onStart?.Invoke(this);
        }

        public void OnUpdate()
        {
            bool stop = false;
            // timer
            if (timer.enable)
            {
                progress = timer.Completion;
                stop = timer.Update();
            }
            // update
            onUpdate?.Invoke(this);

            // stop?
            if (stop)
                Status = TaskStatus.Stop;
        }

        public void OnStop()
        {
            progress = 1;
            timer.End();
            onStop?.Invoke(this);
        }
    }

    [Serializable]
    public class Task : Task<object>
    {
        public Task() { }

        public Task(float time)
        {
            SetDuration(time);
        }
    }
}